/**
 * JSA Widget/Base Abstract class plugin
 *
 * @example
 * Widget = function( settings ) {
 *     return {
 *         __extends__ : jsa.WidgetAbstract,
 *         HTML_PARSER : {
 *             toolbar : 'div.toolbar'
 *         },
 *         init : function() {
 *             console.log('init performed');
 *         },
 *         renderUI : function() {
 *             console.log('renderUI performed');
 *         },
 *         syncUI : function() {
 *             console.log('syncUI performed');
 *         // bind a handler to this.node.toolbar
 *         }
 *     };
 * };
 *
 * var o = Widget.createInstance( { boundingBox: $('div#widget') } );
 * // init performed
 * // renderUI performed
 * // syncUI performed
 * console.log(o.node); // contains boundingBox and toolbar
 *
 * @package JSA.Widget
 * @author sheiko
 * @version 2.03
 * @license MIT
 * @copyright (c) Dmitry Sheiko http://www.dsheiko.com
 * @jscs standard:Jquery
 * Code style: http://docs.jquery.com/JQuery_Core_Style_Guidelines
 */
/*jshint sub:true*/
/*global module: false */
(function( global, undefined ) {
    "use strict";
    global.jsa = global.jsa || {};
    /**
     * Configure your own querySelector function
     * @param string selector
     * @param object context (optional)
     */
    global.jsa.querySelectorFn = global.jsa.querySelectorFn || global.jQuery;

    /**
     * Hook available for instaces of global.jsa.WidgetAbstract
     * @param {object} instace
     * @param {array} args
     */
    global.jsa.Hook.push(function ( instance, args ) {
        var settings = args[ 0 ];
        if ( instance instanceof global.jsa.WidgetAbstract === false ) {
            return;
        }
        if ( settings === undefined || settings.boundingBox === undefined ) {
        throw new TypeError( "Widget derivative is expected to get an argument, " +
            "which contains settings object with boundingBox property" );
        }
        instance.settings = settings;
        instance.node = {};
        instance.node.boundingBox = global.jsa.querySelectorFn( settings.boundingBox );
        if ( instance.HTML_PARSER ) {
                for ( var i in instance.HTML_PARSER) {
                    if (instance.HTML_PARSER.hasOwnProperty( i )) {
                    instance.node[ i ] = global.jsa.querySelectorFn( instance.HTML_PARSER[ i ],
                        instance.node.boundingBox );
                    }
            }
        }
     });

    /**
     * Hook available for instaces of global.jsa.BaseAbstract
     * @param {object} instace
     */
    global.jsa.Hook.push(function ( instance ) {
        if ( instance instanceof global.jsa.BaseAbstract === false ) {
            return;
        }
        var bootstrapMethods = [ 'init', 'renderUI', 'syncUI' ],
            i = 0,
            len = bootstrapMethods.length;
        for (; i < len; i++) {
            instance[bootstrapMethods[ i ]] && instance [bootstrapMethods[ i ]]();
        }

    });
    /**
     * Base is designed to be a low-level foundation class from which other
     * classes can be derived. It tries to invoke automatically init, renderUI, syncUI methods
     * of every class the last successor class inherit
     **/
     global.jsa.BaseAbstract = function () {
         return {};
     };

     /**
     * Widget is the foundation class from which all widgets are derived.
     * It provides the following pieces of core functionality on top of
     * what BaseAbstract already provides:
     *  - A common set of widget attributes
     *  - Consistent markup generation support
     */
    global.jsa.WidgetAbstract = function ( settings ) {
         return {
             "__extends__": global.jsa.BaseAbstract
         };
    };
}( this ));